from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.service.dict_service import DictDataService
from module_admin.dao.jkyx_dao import JkyxDao
from module_admin.entity.vo.jkyx_vo import DeleteJkyxModel, JkyxModel, JkyxPageQueryModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil
from config.env import UploadConfig
from PIL import Image,ImageEnhance
import os

class JkyxService:
    """
    监控影像处理记录模块服务层
    """

    @classmethod
    async def get_jkyx_list_services(
        cls, query_db: AsyncSession, query_object: JkyxPageQueryModel, is_page: bool = False
    ):
        """
        获取监控影像处理记录列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 监控影像处理记录列表信息对象
        """
        jkyx_list_result = await JkyxDao.get_jkyx_list(query_db, query_object, is_page)

        return jkyx_list_result


    @classmethod
    async def add_jkyx_services(cls, query_db: AsyncSession, page_object: JkyxModel):
        """
        新增监控影像处理记录信息service

        :param query_db: orm对象
        :param page_object: 新增监控影像处理记录对象
        :return: 新增监控影像处理记录校验结果
        """
        try:
            # 读取原始文件并处理（添加水印），输出到相同目录下并在原文件名后追加“_watermark”

            relative_path: str = page_object.file_path

            relative_path = relative_path.replace('/profile/','')

            abs_path = os.path.join(UploadConfig.UPLOAD_PATH, relative_path)
            image = Image.open(abs_path)

            # 亮度增强(随便处理一下 示例)
            enhancer = ImageEnhance.Brightness(image)
            img_bright = enhancer.enhance(1.5)  # >1变亮, <1变暗
            
            # 保存到与原图相同的目录，文件名追加 _watermark，保留原扩展名
            dir_path = os.path.dirname(abs_path)
            base_name = os.path.basename(abs_path)
            name, ext = os.path.splitext(base_name)
            save_path = os.path.join(dir_path, f"{name}_watermark{ext if ext else '.png'}")
            img_bright.save(save_path)
            page_object.result_path = '/profile/' + relative_path.replace('.png','_watermark.png')
            
            # ...
            await JkyxDao.add_jkyx_dao(query_db, page_object)
            await query_db.commit()
            return CrudResponseModel(is_success=True, message='新增成功')
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_jkyx_services(cls, query_db: AsyncSession, page_object: JkyxModel):
        """
        编辑监控影像处理记录信息service

        :param query_db: orm对象
        :param page_object: 编辑监控影像处理记录对象
        :return: 编辑监控影像处理记录校验结果
        """
        edit_jkyx = page_object.model_dump(exclude_unset=True, exclude={'user_id', 'type', 'create_time', 'user_name'})
        jkyx_info = await cls.jkyx_detail_services(query_db, page_object.id)
        if jkyx_info.id:
            try:
                await JkyxDao.edit_jkyx_dao(query_db, edit_jkyx)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='更新成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='监控影像处理记录不存在')

    @classmethod
    async def delete_jkyx_services(cls, query_db: AsyncSession, page_object: DeleteJkyxModel):
        """
        删除监控影像处理记录信息service

        :param query_db: orm对象
        :param page_object: 删除监控影像处理记录对象
        :return: 删除监控影像处理记录校验结果
        """
        if page_object.ids:
            id_list = page_object.ids.split(',')
            try:
                for id in id_list:
                    await JkyxDao.delete_jkyx_dao(query_db, JkyxModel(id=id))
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='删除成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='传入主键为空')

    @classmethod
    async def jkyx_detail_services(cls, query_db: AsyncSession, id: int):
        """
        获取监控影像处理记录详细信息service

        :param query_db: orm对象
        :param id: 主键
        :return: 主键对应的信息
        """
        jkyx = await JkyxDao.get_jkyx_detail_by_id(query_db, id=id)
        if jkyx:
            result = JkyxModel(**CamelCaseUtil.transform_result(jkyx))
        else:
            result = JkyxModel(**dict())

        return result

    @staticmethod
    async def export_jkyx_list_services(request: Request, jkyx_list: List):
        """
        导出监控影像处理记录信息service

        :param jkyx_list: 监控影像处理记录信息列表
        :return: 监控影像处理记录信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            'id': '主键',
            'userId': '用户id',
            'type': '处理类型：1去除雨雾雪 2xx',
            'filePath': '文件路径',
            'createTime': '创建时间',
            'userName': '用户名',
        }
        sys_jkyx_type_list = await DictDataService.query_dict_data_list_from_cache_services(
            request.app.state.redis, dict_type='sys_jkyx_type'
        )
        sys_jkyx_type_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in sys_jkyx_type_list]
        sys_jkyx_type_option_dict = {item.get('value'): item for item in sys_jkyx_type_option}
        for item in jkyx_list:
            if str(item.get('type')) in sys_jkyx_type_option_dict.keys():
                item['type'] = sys_jkyx_type_option_dict.get(str(item.get('type'))).get('label')
        binary_data = ExcelUtil.export_list2excel(jkyx_list, mapping_dict)

        return binary_data
